1 <?php
2 /*
3  * smtp.php
4  *
5  * @(#) $Header: /home/mlemos/cvsroot/smtp/smtp.php,v
1.37 2004/10/05 04:00:46 mlemos Exp $
6  *
7  */

8
9 class
smtp_class
10 {
11     
var $user="";
12     
var $realm="";
13     
var $password="";
14     
var $workstation="";
15     
var $authentication_mechanism="";
16     
var $host_name="";
17     
var $host_port=25;
18     
var $localhost="";
19     
var $timeout=0;
20     
var $data_timeout=0;
21     
var $direct_delivery=0;
22     
var $error="";
23     
var $debug=0;
24     
var $html_debug=0;
25     
var $esmtp=1;
26     
var $esmtp_host="";
27     
var $esmtp_extensions=array();
28     
var $maximum_piped_recipients=100;
29     
var $exclude_address="";
30     
var $getmxrr="GetMXRR";
31     
var $pop3_auth_host="";
32     
var $pop3_auth_port=110;
33
34     
/* private variables - DO NOT ACCESS */
35
36     
var $state="Disconnected";
37     
var $connection=0;
38     
var $pending_recipients=0;
39     
var $next_token="";
40     
var $direct_sender="";
41     
var $connected_domain="";
42     
var $result_code;
43
44     
/* Private methods - DO NOT CALL */
45
46     Function Tokenize($
string,$separator="")
47     {
48         
if(!strcmp($separator,""))
49         {
50             $separator=$
string;
51             $
string=$this->next_token;
52         }
53         
for($character=0;$character<strlen($separator);$character++)
54         {
55             
if(GetType($position=strpos($string,$separator[$character]))=="integer")
56                 $found=(IsSet($found) ? min($found,$position) : $position);
57         }
58         
if(IsSet($found))
59         {
60             $
this->next_token=substr($string,$found+1);
61             
return(substr($string,0,$found));
62         }
63         
else
64         {
65             $
this->next_token="";
66             
return($string);
67         }
68     }
69
70     Function OutputDebug($message)
71     {
72         $message.=
"\n";
73         
if($this->html_debug)
74             $message=str_replace(
"\n","<br />\n",HtmlEntities($message));
75         echo $message;
76         flush();
77     }
78
79     Function SetDataAccessError($error)
80     {
81         $
this->error=$error;
82         
if(function_exists("socket_get_status"))
83         {
84             $status=socket_get_status($
this->connection);
85             
if($status["timed_out"])
86                 $
this->error.=": data access time out";
87             elseif($status[
"eof"])
88                 $
this->error.=": the server disconnected";
89         }
90     }
91
92     Function GetLine()
93     {
94         
for($line="";;)
95         {
96             
if(feof($this->connection))
97             {
98                 $
this->error="reached the end of data while reading from the SMTP server conection";
99                 
return("");
100             }
101             
if(GetType($data=fgets($this->connection,100))!="string"
102             || strlen($data)==
0)
103             {
104                 $
this->SetDataAccessError("it was not possible to read line from the SMTP server");
105                 
return("");
106             }
107             $line.=$data;
108             $length=strlen($line);
109             
if($length>=2
110             && substr($line,$length-
2,2)=="\r\n")
111             {
112                 $line=substr($line,
0,$length-2);
113                 
if($this->debug)
114                     $
this->OutputDebug("S $line");
115                 
return($line);
116             }
117         }
118     }
119
120     Function PutLine($line)
121     {
122         
if($this->debug)
123             $
this->OutputDebug("C $line");
124         
if(!fputs($this->connection,"$line\r\n"))
125         {
126             $
this->SetDataAccessError("it was not possible to send a line to the SMTP server");
127             
return(0);
128         }
129         
return(1);
130     }
131
132     Function PutData(&$data)
133     {
134         
if(strlen($data))
135         {
136             
if($this->debug)
137                 $
this->OutputDebug("C $data");
138             
if(!fputs($this->connection,$data))
139             {
140                 $
this->SetDataAccessError("it was not possible to send data to the SMTP server");
141                 
return(0);
142             }
143         }
144         
return(1);
145     }
146
147     Function VerifyResultLines($code,&$responses)
148     {
149         $responses=array();
150         Unset($
this->result_code);
151         
while(strlen($line=$this->GetLine($this->connection)))
152         {
153             
if(IsSet($this->result_code))
154             {
155                 
if(strcmp($this->Tokenize($line," -"),$this->result_code))
156                 {
157                     $
this->error=$line;
158                     
return(0);
159                 }
160             }
161             
else
162             {
163                 $
this->result_code=$this->Tokenize($line," -");
164                 
if(GetType($code)=="array")
165                 {
166                     
for($codes=0;$codes<count($code) && strcmp($this->result_code,$code[$codes]);$codes++);
167                     
if($codes>=count($code))
168                     {
169                         $
this->error=$line;
170                         
return(0);
171                     }
172                 }
173                 
else
174                 {
175                     
if(strcmp($this->result_code,$code))
176                     {
177                         $
this->error=$line;
178                         
return(0);
179                     }
180                 }
181             }
182             $responses[]=$
this->Tokenize("");
183             
if(!strcmp($this->result_code,$this->Tokenize($line," ")))
184                 
return(1);
185         }
186         
return(-1);
187     }
188
189     Function FlushRecipients()
190     {
191         
if($this->pending_sender)
192         {
193             
if($this->VerifyResultLines("250",$responses)<=0)
194                 
return(0);
195             $
this->pending_sender=0;
196         }
197         
for(;$this->pending_recipients;$this->pending_recipients--)
198         {
199             
if($this->VerifyResultLines(array("250","251"),$responses)<=0)
200                 
return(0);
201         }
202         
return(1);
203     }
204
205     Function ConnectToHost($domain, $port, $resolve_message)
206     {
207         
if(ereg('^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$',$domain))
208             $ip=$domain;
209         
else
210         {
211             
if($this->debug)
212                 $
this->OutputDebug($resolve_message);
213             
if(!strcmp($ip=@gethostbyname($domain),$domain))
214                 
return("could not resolve host \"".$domain."\"");
215         }
216         
if(strlen($this->exclude_address)
217         && !strcmp(@gethostbyname($
this->exclude_address),$ip))
218             
return("domain \"".$domain."\" resolved to an address excluded to be valid");
219         
if($this->debug)
220             $
this->OutputDebug("Connecting to host address \"".$ip."\"...");
221         
if(($this->connection=($this->timeout ? @fsockopen($ip,$port,$errno,$error,$this->timeout) : @fsockopen($ip,$port))))
222             
return("");
223         $error=($
this->timeout ? strval($error) : "??");
224         
switch($error)
225         {
226             
case "-3":
227                 
return("-3 socket could not be created");
228             
case "-4":
229                 
return("-4 dns lookup on hostname \"".$domain."\" failed");
230             
case "-5":
231                 
return("-5 connection refused or timed out");
232             
case "-6":
233                 
return("-6 fdopen() call failed");
234             
case "-7":
235                 
return("-7 setvbuf() call failed");
236         }
237         
return("could not connect to the host \"".$domain."\": ".$error);
238     }
239
240     Function SASLAuthenticate($mechanisms, $credentials, &$authenticated, &$mechanism)
241     {
242         $authenticated=
0;
243         
if(!function_exists("class_exists")
244         || !class_exists(
"sasl_client_class"))
245         {
246             $
this->error="it is not possible to authenticate using the specified mechanism because the SASL library class is not loaded";
247             
return(0);
248         }
249         $sasl=
new sasl_client_class;
250         $sasl->SetCredential(
"user",$credentials["user"]);
251         $sasl->SetCredential(
"password",$credentials["password"]);
252         
if(IsSet($credentials["realm"]))
253             $sasl->SetCredential(
"realm",$credentials["realm"]);
254         
if(IsSet($credentials["workstation"]))
255             $sasl->SetCredential(
"workstation",$credentials["workstation"]);
256         
if(IsSet($credentials["mode"]))
257             $sasl->SetCredential(
"mode",$credentials["mode"]);
258         
do
259         {
260             $status=$sasl->Start($mechanisms,$message,$interactions);
261         }
262         
while($status==SASL_INTERACT);
263         
switch($status)
264         {
265             
case SASL_CONTINUE:
266                 
break;
267             
case SASL_NOMECH:
268                 
if(strlen($this->authentication_mechanism))
269                 {
270                     $
this->error="authenticated mechanism ".$this->authentication_mechanism." may not be used: ".$sasl->error;
271                     
return(0);
272                 }
273                 
break;
274             
default:
275                 $
this->error="Could not start the SASL authentication client: ".$sasl->error;
276                 
return(0);
277         }
278         
if(strlen($mechanism=$sasl->mechanism))
279         {
280             
if($this->PutLine("AUTH ".$sasl->mechanism.(IsSet($message) ? " ".base64_encode($message) : ""))==0)
281             {
282                 $
this->error="Could not send the AUTH command";
283                 
return(0);
284             }
285             
if(!$this->VerifyResultLines(array("235","334"),$responses))
286                 
return(0);
287             
switch($this->result_code)
288             {
289                 
case "235":
290                     $response=
"";
291                     $authenticated=
1;
292                     
break;
293                 
case "334":
294                     $response=base64_decode($responses[
0]);
295                     
break;
296                 
default:
297                     $
this->error="Authentication error: ".$responses[0];
298                     
return(0);
299             }
300             
for(;!$authenticated;)
301             {
302                 
do
303                 {
304                     $status=$sasl->Step($response,$message,$interactions);
305                 }
306                 
while($status==SASL_INTERACT);
307                 
switch($status)
308                 {
309                     
case SASL_CONTINUE:
310                         
if($this->PutLine(base64_encode($message))==0)
311                         {
312                             $
this->error="Could not send the authentication step message";
313                             
return(0);
314                         }
315                         
if(!$this->VerifyResultLines(array("235","334"),$responses))
316                             
return(0);
317                         
switch($this->result_code)
318                         {
319                             
case "235":
320                                 $response=
"";
321                                 $authenticated=
1;
322                                 
break;
323                             
case "334":
324                                 $response=base64_decode($responses[
0]);
325                                 
break;
326                             
default:
327                                 $
this->error="Authentication error: ".$responses[0];
328                                 
return(0);
329                         }
330                         
break;
331                     
default:
332                         $
this->error="Could not process the SASL authentication step: ".$sasl->error;
333                         
return(0);
334                 }
335             }
336         }
337         
return(1);
338     }
339
340     
/* Public methods */
341
342     Function Connect($domain=
"")
343     {
344         
if(strcmp($this->state,"Disconnected"))
345         {
346             $
this->error="connection is already established";
347             
return(0);
348         }
349         $
this->error=$error="";
350         $
this->esmtp_host="";
351         $
this->esmtp_extensions=array();
352         $hosts=array();
353         
if($this->direct_delivery)
354         {
355             
if(strlen($domain)==0)
356                 
return(1);
357             $hosts=$weights=$mxhosts=array();
358             $getmxrr=$
this->getmxrr;
359             
if(function_exists($getmxrr)
360             && $getmxrr($domain,$hosts,$weights))
361             {
362                 
for($host=0;$host<count($hosts);$host++)
363                     $mxhosts[$weights[$host]]=$hosts[$host];
364                 KSort($mxhosts);
365                 
for(Reset($mxhosts),$host=0;$host<count($mxhosts);Next($mxhosts),$host++)
366                     $hosts[$host]=$mxhosts[Key($mxhosts)];
367             }
368             
else
369             {
370                 
if(strcmp(@gethostbyname($domain),$domain)!=0)
371                     $hosts[]=$domain;
372             }
373         }
374         
else
375         {
376             
if(strlen($this->host_name))
377                 $hosts[]=$
this->host_name;
378             
if(strlen($this->pop3_auth_host))
379             {
380                 $user=$
this->user;
381                 
if(strlen($user)==0)
382                 {
383                     $
this->error="it was not specified the POP3 authentication user";
384                     
return(0);
385                 }
386                 $password=$
this->password;
387                 
if(strlen($password)==0)
388                 {
389                     $
this->error="it was not specified the POP3 authentication password";
390                     
return(0);
391                 }
392                 $domain=$
this->pop3_auth_host;
393                 $
this->error=$this->ConnectToHost($domain, $this->pop3_auth_port, "Resolving POP3 authentication host \"".$domain."\"...");
394                 
if(strlen($this->error))
395                     
return(0);
396                 
if(strlen($response=$this->GetLine())==0)
397                     
return(0);
398                 
if(strcmp($this->Tokenize($response," "),"+OK"))
399                 {
400                     $
this->error="POP3 authentication server greeting was not found";
401                     
return(0);
402                 }
403                 
if(!$this->PutLine("USER ".$this->user)
404                 || strlen($response=$
this->GetLine())==0)
405                     
return(0);
406                 
if(strcmp($this->Tokenize($response," "),"+OK"))
407                 {
408                     $
this->error="POP3 authentication user was not accepted: ".$this->Tokenize("\r\n");
409                     
return(0);
410                 }
411                 
if(!$this->PutLine("PASS ".$password)
412                 || strlen($response=$
this->GetLine())==0)
413                     
return(0);
414                 
if(strcmp($this->Tokenize($response," "),"+OK"))
415                 {
416                     $
this->error="POP3 authentication password was not accepted: ".$this->Tokenize("\r\n");
417                     
return(0);
418                 }
419                 fclose($
this->connection);
420                 $
this->connection=0;
421             }
422         }
423         
if(count($hosts)==0)
424         {
425             $
this->error="could not determine the SMTP to connect";
426             
return(0);
427         }
428         
for($host=0, $error="not connected";strlen($error) && $host<count($hosts);$host++)
429         {
430             $domain=$hosts[$host];
431             $error=$
this->ConnectToHost($domain, $this->host_port, "Resolving SMTP server domain \"$domain\"...");
432         }
433         
if(strlen($error))
434         {
435             $
this->error=$error;
436             
return(0);
437         }
438         $timeout=($
this->data_timeout ? $this->data_timeout : $this->timeout);
439         
if($timeout
440         && function_exists(
"socket_set_timeout"))
441             socket_set_timeout($
this->connection,$timeout,0);
442         
if($this->debug)
443             $
this->OutputDebug("Connected to SMTP server \"".$domain."\".");
444         
if(!strcmp($localhost=$this->localhost,"")
445         && !strcmp($localhost=getenv(
"SERVER_NAME"),"")
446         && !strcmp($localhost=getenv(
"HOST"),""))
447             $localhost=
"localhost";
448         $success=
0;
449         
if($this->VerifyResultLines("220",$responses)>0)
450         {
451             $fallback=
1;
452             
if($this->esmtp
453             || strlen($
this->user))
454             {
455                 
if($this->PutLine("EHLO $localhost"))
456                 {
457                     
if(($success_code=$this->VerifyResultLines("250",$responses))>0)
458                     {
459                         $
this->esmtp_host=$this->Tokenize($responses[0]," ");
460                         
for($response=1;$response<count($responses);$response++)
461                         {
462                             $extension=strtoupper($
this->Tokenize($responses[$response]," "));
463                             $
this->esmtp_extensions[$extension]=$this->Tokenize("");
464                         }
465                         $success=
1;
466                         $fallback=
0;
467                     }
468                     
else
469                     {
470                         
if($success_code==0)
471                         {
472                             $code=$
this->Tokenize($this->error," -");
473                             
switch($code)
474                             {
475                                 
case "421":
476                                     $fallback=
0;
477                                     
break;
478                             }
479                         }
480                     }
481                 }
482                 
else
483                     $fallback=
0;
484             }
485             
if($fallback)
486             {
487                 
if($this->PutLine("HELO $localhost")
488                 && $
this->VerifyResultLines("250",$responses)>0)
489                     $success=
1;
490             }
491             
if($success
492             && strlen($
this->user)
493             && strlen($
this->pop3_auth_host)==0)
494             {
495                 
if(!IsSet($this->esmtp_extensions["AUTH"]))
496                 {
497                     $
this->error="server does not require authentication";
498                     $success=
0;
499                 }
500                 
else
501                 {
502                     
if(strlen($this->authentication_mechanism))
503                         $mechanisms=array($
this->authentication_mechanism);
504                     
else
505                     {
506                         $mechanisms=array();
507                         
for($authentication=$this->Tokenize($this->esmtp_extensions["AUTH"]," ");strlen($authentication);$authentication=$this->Tokenize(" "))
508                             $mechanisms[]=$authentication;
509                     }
510                     $credentials=array(
511                         
"user"=>$this->user,
512                         
"password"=>$this->password
513                     );
514                     
if(strlen($this->realm))
515                         $credentials[
"realm"]=$this->realm;
516                     
if(strlen($this->workstation))
517                         $credentials[
"workstation"]=$this->workstation;
518                     $success=$
this->SASLAuthenticate($mechanisms,$credentials,$authenticated,$mechanism);
519                     
if(!$success
520                     && !strcmp($mechanism,
"PLAIN"))
521                     {
522                         
/*
523                          * Author: Russell Robinson,
25 May 2003, http://www.tectite.com/
524                          * Purpose: Try various AUTH PLAIN authentication methods.
525                          */

526                         $mechanisms=array(
"PLAIN");
527                         $credentials=array(
528                             
"user"=>$this->user,
529                             
"password"=>$this->password
530                         );
531                         
if(strlen($this->realm))
532                         {
533                             
/*
534                              * According to: http://www.sendmail.org/~ca/email/authrealms.html#authpwcheck_method
535                              * some sendmails won
't accept the realm, so try again without it
536                              */

537                             $success=$
this->SASLAuthenticate($mechanisms,$credentials,$authenticated,$mechanism);
538                         }
539                         
if(!$success)
540                         {
541                             
/*
542                              * It was seen an EXIM configuration like
this:
543                              * user^password^unused
544                              */

545                             $credentials[
"mode"]=SASL_PLAIN_EXIM_DOCUMENTATION_MODE;
546                             $success=$
this->SASLAuthenticate($mechanisms,$credentials,$authenticated,$mechanism);
547                         }
548                         
if(!$success)
549                         {
550                             
/*
551                              * ... though: http://exim.work.de/exim-html-
3.20/doc/html/spec_36.html
552                              * specifies: ^user^password
553                              */

554                             $credentials[
"mode"]=SASL_PLAIN_EXIM_MODE;
555                             $success=$
this->SASLAuthenticate($mechanisms,$credentials,$authenticated,$mechanism);
556                         }
557                     }
558                     
if($success
559                     && strlen($mechanism)==
0)
560                     {
561                         $
this->error="it is not supported any of the authentication mechanisms required by the server";
562                         $success=
0;
563                     }
564                 }
565             }
566         }
567         
if($success)
568         {
569             $
this->state="Connected";
570             $
this->connected_domain=$domain;
571         }
572         
else
573         {
574             fclose($
this->connection);
575             $
this->connection=0;
576         }
577         
return($success);
578     }
579
580     Function MailFrom($sender)
581     {
582         
if($this->direct_delivery)
583         {
584             
switch($this->state)
585             {
586                 
case "Disconnected":
587                     $
this->direct_sender=$sender;
588                     
return(1);
589                 
case "Connected":
590                     $sender=$
this->direct_sender;
591                     
break;
592                 
default:
593                     $
this->error="direct delivery connection is already established and sender is already set";
594                     
return(0);
595             }
596         }
597         
else
598         {
599             
if(strcmp($this->state,"Connected"))
600             {
601                 $
this->error="connection is not in the initial state";
602                 
return(0);
603             }
604         }
605         $
this->error="";
606         
if(!$this->PutLine("MAIL FROM:<$sender>"))
607             
return(0);
608         
if(!IsSet($this->esmtp_extensions["PIPELINING"])
609         && $
this->VerifyResultLines("250",$responses)<=0)
610             
return(0);
611         $
this->state="SenderSet";
612         
if(IsSet($this->esmtp_extensions["PIPELINING"]))
613             $
this->pending_sender=1;
614         $
this->pending_recipients=0;
615         
return(1);
616     }
617
618     Function SetRecipient($recipient)
619     {
620         
if($this->direct_delivery)
621         {
622             
if(GetType($at=strrpos($recipient,"@"))!="integer")
623                 
return("it was not specified a valid direct recipient");
624             $domain=substr($recipient,$at+
1);
625             
switch($this->state)
626             {
627                 
case "Disconnected":
628                     
if(!$this->Connect($domain))
629                         
return(0);
630                     
if(!$this->MailFrom(""))
631                     {
632                         $error=$
this->error;
633                         $
this->Disconnect();
634                         $
this->error=$error;
635                         
return(0);
636                     }
637                     
break;
638                 
case "SenderSet":
639                 
case "RecipientSet":
640                     
if(strcmp($this->connected_domain,$domain))
641                     {
642                         $
this->error="it is not possible to deliver directly to recipients of different domains";
643                         
return(0);
644                     }
645                     
break;
646                 
default:
647                     $
this->error="connection is already established and the recipient is already set";
648                     
return(0);
649             }
650         }
651         
else
652         {
653             
switch($this->state)
654             {
655                 
case "SenderSet":
656                 
case "RecipientSet":
657                     
break;
658                 
default:
659                     $
this->error="connection is not in the recipient setting state";
660                     
return(0);
661             }
662         }
663         $
this->error="";
664         
if(!$this->PutLine("RCPT TO:<$recipient>"))
665             
return(0);
666         
if(IsSet($this->esmtp_extensions["PIPELINING"]))
667         {
668             $
this->pending_recipients++;
669             
if($this->pending_recipients>=$this->maximum_piped_recipients)
670             {
671                 
if(!$this->FlushRecipients())
672                     
return(0);
673             }
674         }
675         
else
676         {
677             
if($this->VerifyResultLines(array("250","251"),$responses)<=0)
678                 
return(0);
679         }
680         $
this->state="RecipientSet";
681         
return(1);
682     }
683
684     Function StartData()
685     {
686         
if(strcmp($this->state,"RecipientSet"))
687         {
688             $
this->error="connection is not in the start sending data state";
689             
return(0);
690         }
691         $
this->error="";
692         
if(!$this->PutLine("DATA"))
693             
return(0);
694         
if($this->pending_recipients)
695         {
696             
if(!$this->FlushRecipients())
697                 
return(0);
698         }
699         
if($this->VerifyResultLines("354",$responses)<=0)
700             
return(0);
701         $
this->state="SendingData";
702         
return(1);
703     }
704
705     Function PrepareData(&$data,&$output,$preg=
1)
706     {
707         
if($preg
708         && function_exists(
"preg_replace"))
709             $output=preg_replace(array(
"/\n\n|\r\r/","/(^|[^\r])\n/","/\r([^\n]|\$)/D","/(^|\n)\\./"),array("\r\n\r\n","\\1\r\n","\r\n\\1","\\1.."),$data);
710         
else
711             $output=ereg_replace(
"(^|\n)\\.","\\1..",ereg_replace("\r([^\n]|\$)","\r\n\\1",ereg_replace("(^|[^\r])\n","\\1\r\n",ereg_replace("\n\n|\r\r","\r\n\r\n",$data))));
712     }
713
714     Function SendData($data)
715     {
716         
if(strcmp($this->state,"SendingData"))
717         {
718             $
this->error="connection is not in the sending data state";
719             
return(0);
720         }
721         $
this->error="";
722         
return($this->PutData($data));
723     }
724
725     Function EndSendingData()
726     {
727         
if(strcmp($this->state,"SendingData"))
728         {
729             $
this->error="connection is not in the sending data state";
730             
return(0);
731         }
732         $
this->error="";
733         
if(!$this->PutLine("\r\n.")
734         || $
this->VerifyResultLines("250",$responses)<=0)
735             
return(0);
736         $
this->state="Connected";
737         
return(1);
738     }
739
740     Function ResetConnection()
741     {
742         
switch($this->state)
743         {
744             
case "Connected":
745                 
return(1);
746             
case "SendingData":
747                 $
this->error="can not reset the connection while sending data";
748                 
return(0);
749             
case "Disconnected":
750                 $
this->error="can not reset the connection before it is established";
751                 
return(0);
752         }
753         $
this->error="";
754         
if(!$this->PutLine("RSET")
755         || $
this->VerifyResultLines("250",$responses)<=0)
756             
return(0);
757         $
this->state="Connected";
758         
return(1);
759     }
760
761     Function Disconnect($quit=
1)
762     {
763         
if(!strcmp($this->state,"Disconnected"))
764         {
765             $
this->error="it was not previously established a SMTP connection";
766             
return(0);
767         }
768         $
this->error="";
769         
if(!strcmp($this->state,"Connected")
770         && $quit
771         && (!$
this->PutLine("QUIT")
772         || $
this->VerifyResultLines("221",$responses)<=0))
773             
return(0);
774         fclose($
this->connection);
775         $
this->connection=0;
776         $
this->state="Disconnected";
777         
if($this->debug)
778             $
this->OutputDebug("Disconnected.");
779         
return(1);
780     }
781
782     Function SendMessage($sender,$recipients,$headers,$body)
783     {
784         
if(($success=$this->Connect()))
785         {
786             
if(($success=$this->MailFrom($sender)))
787             {
788                 
for($recipient=0;$recipient<count($recipients);$recipient++)
789                 {
790                     
if(!($success=$this->SetRecipient($recipients[$recipient])))
791                         
break;
792                 }
793                 
if($success
794                 && ($success=$
this->StartData()))
795                 {
796                     
for($header_data="",$header=0;$header<count($headers);$header++)
797                         $header_data.=$headers[$header].
"\r\n";
798                     
if(($success=$this->SendData($header_data."\r\n")))
799                     {
800                         $
this->PrepareData($body,$body_data);
801                         $success=$
this->SendData($body_data);
802                     }
803                     
if($success)
804                         $success=$
this->EndSendingData();
805                 }
806             }
807             $error=$
this->error;
808             $disconnect_success=$
this->Disconnect($success);
809             
if($success)
810                 $success=$disconnect_success;
811             
else
812                 $
this->error=$error;
813         }
814         
return($success);
815     }
816
817 };
818
819 ?>



Full source code website bán hàng thương mại điện tử gần giống shopee 473.307 lượt xem

Gõ tìm kiếm nhanh...